"""
Description: 用户控制层
Author: 月间
Date: 2024-12-11 22:16:04
LastEditTime: 2025-03-23 17:49:18
LastEditors:
"""

from fastapi import APIRouter, Depends, Response
from fastapi_utils.cbv import cbv
from sqlalchemy.ext.asyncio import AsyncSession

from authx.core.auth_util import AuthUtil
from authx.dependencies.permission import PermissionChecker
from authx.models.session import TerminalInfoModel
from src.core.base_controller import BaseController
from src.core.dependencies import IdList
from src.core.response.response_schema import (
    ResponseGenericSchema,
    ResponseSchema,
    PageResponse,
)
from src.db.db_database import alchemy
from src.models import SysUser
from src.schemas.user_info_schema import UserInfo
from src.schemas.user_schema import (
    UserOut,
    UserParams,
    UserCreate,
    UserUpdate,
    SimpleOnlineUser,
    OnlineUserParams,
)
from src.services.user_service import UserService

router = APIRouter()


@cbv(router)
class UserController(BaseController):
    """
    用户视图
    """

    db: AsyncSession = Depends(alchemy.provide_session())
    user_service: UserService = Depends(alchemy.provide_service(UserService))

    @router.get(
        "/list",
        summary="用户列表",
        response_model=PageResponse[UserOut],
        dependencies=[Depends(PermissionChecker("system:user:list"))],
    )
    async def get_user_list(self, param: UserParams = Depends()):
        where = await param.get_where_and_limit_offset(SysUser)
        res, count = await self.user_service.list_and_count(
            *where,
            load=[SysUser.roles, SysUser.posts, SysUser.dept],
        )
        res_list: list[UserOut] = [UserOut.model_validate(item) for item in res]
        for item in res_list:
            item.role_ids = [i.id for i in item.roles]
            item.post_ids = [i.id for i in item.posts]
        return self.paginated_response(
            data=res_list, total=count, current=param.page, size=param.limit
        )

    @router.get(
        "/online/users",
        summary="在线用户列表（树状表格第一层）",
        response_model=PageResponse[SimpleOnlineUser],
        dependencies=[Depends(PermissionChecker("system:user:online"))],
    )
    async def get_online_users_tree(self, param: OnlineUserParams = Depends()):
        """
        获取所有在线用户基本信息（用于树状表格第一层）
        返回格式：[{用户基本信息, device_count, is_online}]
        不包含角色、部门、岗位等信息
        前端负责树结构构建，点击时通过/online/user/{user_id}/devices获取设备信息
        """
        online_users = await self.user_service.get_online_users()
        return self.paginated_response(data=online_users)

    @router.get(
        "/online/user/{user_id}/devices",
        summary="获取用户设备信息",
        response_model=ResponseGenericSchema[list[TerminalInfoModel]],
        dependencies=[Depends(PermissionChecker("system:user:online"))],
    )
    async def get_user_devices(self, user_id: int):
        """
        获取指定用户的所有登录设备信息
        """
        devices = await self.user_service.get_user_devices(user_id)
        return self.success(data=devices)

    @router.post(
        "/add",
        summary="创建用户",
        description="创建用户",
        dependencies=[Depends(PermissionChecker("system:user:add"))],
        response_model=ResponseSchema,
    )
    async def add_user(self, model: UserCreate):
        await self.user_service.create_user(model)
        return self.success(message="创建成功")

    @router.put(
        "/update",
        summary="更新用户",
        description="更新用户",
        dependencies=[Depends(PermissionChecker("system:user:update"))],
        response_model=ResponseSchema,
    )
    async def update_user(
        self,
        model: UserUpdate,
        user_id: str = Depends(PermissionChecker("system:user:update")),
    ):
        # 不能自己操作自己
        if user_id == model.id:
            return self.error(message="不能自己操作自己, 跟新个人信息请到个人主页")
        await self.user_service.update_user(model)
        return self.success(message="更新成功")

    @router.delete(
        "/delete",
        summary="删除用户",
        description="删除用户",
        dependencies=[Depends(PermissionChecker("system:user:delete"))],
        response_model=ResponseSchema,
    )
    async def delete_user(
        self,
        ids: IdList = Depends(),
        user: UserInfo = Depends(PermissionChecker("system:user:delete")),
    ):
        # 不能直接删除自己
        if user.id in ids.ids:
            return self.error(message="不能删除自己")
        await self.user_service.delete_many(ids.ids, auto_commit=True)
        return self.success(message="删除成功")

    @router.post(
        "/online/logout-by-token",
        summary="根据token注销用户",
        description="根据token注销指定用户的登录状态",
        dependencies=[Depends(PermissionChecker("system:user:online:logout"))],
        response_model=ResponseSchema,
    )
    async def logout_by_token(self, token: str):
        """
        根据token注销用户的登录状态
        """
        await AuthUtil.logout_by_token_value(token)
        return self.success(message="注销成功")

    @router.post(
        "/online/disable",
        summary="根据token封禁用户",
        description="根据token获取用户ID并封禁用户，默认永久封禁",
        dependencies=[Depends(PermissionChecker("system:user:disable"))],
        response_model=ResponseSchema,
    )
    async def disable(self, login_id: str, time: int = -1):
        """
        根据token封禁用户

        Args:
            login_id: 用户的token值
            time: 封禁时间，单位：秒（-1表示永久封禁）
        """
        # 使用新添加的便捷方法同时完成封禁和注销
        await AuthUtil.disable(login_id, time)
        return self.success(
            message=f"用户已被{'永久' if time == -1 else f'{time}秒'}封禁"
        )

    # 强制注销
    @router.post("/online/logout-by-login-id")
    async def logout_by_login_id(self, response: Response, login_id: str):
        """
        强制下线用户
        """
        await AuthUtil.logout_by_login_id(response, login_id=login_id)
        return self.success(message="强制下线成功")
